package my.assistant.reminder;

import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import my.assistant.R;
import my.assistant.util.Constants;
import my.assistant.util.ReminderUtils;
import my.assistant.util.ResKey;
import my.assistant.util.ResUtils;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckedTextView;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TimePicker;
import android.widget.Toast;

/**
 * TODO: 1.Sound can not be set to every alarm. So when it alarm, the receiver can only get the default one!!!!!!!
 * 2.have not set alarm time.
 * 3.add check for exist time.
 */
public class Reminder extends Activity
{
	private RemindVO remindVO;
	private ArrayAdapter<String> reminderAdapter = null;
	private List<String> idList = new ArrayList<String>();
	private Intent alertIntent;
	private Calendar cal = Calendar.getInstance();

	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.reminder);
		ListView listView = (ListView) findViewById(R.id.listView);
		final Resources resources = getResources();

		alertIntent = new Intent(Reminder.this, AlarmReceiver.class);
		final AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);

		final List<String> reminderList = new ArrayList<String>();
		if (ResUtils.hasKeyPrefix(ResKey.REMINDVO_PREFIX))
		{
			int n = 0;
			int count = 0;
			while (ResUtils.hasKeyPrefix(ResKey.REMINDVO_PREFIX + n))
			{
				reminderList.add(ReminderUtils.buildRemindStr(buff, resources, n));
				idList.add(String.valueOf(n));
				if (Constants.ALERT_SENDER_MAP.containsKey(String.valueOf(n)))
				{
					Log.w(" -- sender --", " init :: " + n);
					Constants.ALERT_SENDER_MAP.put(String.valueOf(n), PendingIntent.getBroadcast(Reminder.this, n,
							alertIntent, n));
				}
				n++;
				count++;
			}
			while (count == 0 && n < Constants.MAX_REMINDER_COUNT)
			{
				n++;
				while (ResUtils.hasKeyPrefix(ResKey.REMINDVO_PREFIX + n))
				{
					Log.w(" -- sender --", " init :: " + n);
					reminderList.add(ReminderUtils.buildRemindStr(buff, resources, n));
					idList.add(String.valueOf(n));
					if (Constants.ALERT_SENDER_MAP.containsKey(String.valueOf(n)))
					{
						Constants.ALERT_SENDER_MAP.put(String.valueOf(n), PendingIntent.getBroadcast(Reminder.this, n,
								alertIntent, n));
					}
					n++;
					count++;
				}
			}
		}
		if (reminderAdapter == null)
		{
			reminderAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice,
			        reminderList);
		}
		listView.setAdapter(reminderAdapter);
		listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
		listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
		{
			@Override
			public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id)
			{
				if (menuBuilder == null)
				{
					menuBuilder = new AlertDialog.Builder(Reminder.this).setIcon(R.drawable.stat_neutral).setTitle(
					        R.string.reminder_add).setItems(R.array.item_menu_popup,
					        new DialogInterface.OnClickListener()
					        {
						        @Override
						        public void onClick(DialogInterface dialog, int which)
						        {
							        switch (which)
							        {
							        case 0:
								        edit = true;
								        editIndex = idList.get(position);
								        remindVO = ReminderUtils.buildReminderVO(Integer.valueOf(editIndex));
								        showAlertDialog();
								        break;
							        case 1:
								        if (delConfirmBuilder == null)
								        {
									        delConfirmBuilder = new AlertDialog.Builder(Reminder.this).setIcon(
									                R.drawable.stat_sad).setTitle(R.string.alert).setPositiveButton(
									                R.string.confirm_ok, new DialogInterface.OnClickListener()
									                {
										                @Override
										                public void onClick(DialogInterface dialog, int which)
										                {
											                ReminderUtils.delReminder(Integer.valueOf(idList
											                        .get(position)));
											                reminderAdapter.remove(reminderAdapter.getItem(position));
											                Constants.ALERT_SENDER_MAP.remove(idList.get(position)).cancel();
											                idList.remove(position);
										                }
									                }).setNegativeButton(R.string.confirm_cancel, null);
								        }
								        delConfirmBuilder.setMessage(R.string.del_confirm);
								        delConfirmBuilder.show();
								        break;
							        }
						        }
					        });
				}
				menuBuilder.show();
				return false;
			}
		});
		listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
		{
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id)
			{
				if (((CheckedTextView) view).isChecked())
				{
					alarm.cancel(Constants.ALERT_SENDER_MAP.get(idList.get(position)));
					Toast.makeText(Reminder.this, R.string.reminder_service_cancel, Toast.LENGTH_SHORT).show();
				} else
				{
					RemindVO tmpVO = ReminderUtils.buildReminderVO(Integer.valueOf(idList.get(position)));
					tmpVO.calculateAlarmTime(cal);
					if (tmpVO.repeatEveryDay())
					{
						alarm.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, tmpVO.alarmTime, Constants.HOUR_24,
								Constants.ALERT_SENDER_MAP.get(idList.get(position)));
					} else
					{
						alarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, tmpVO.alarmTime, Constants.ALERT_SENDER_MAP.get(idList
						        .get(position)));
					}
					Toast.makeText(
					        Reminder.this,
					        resources.getString(R.string.reminder_service_startin) + tmpVO.leftHour
					                + resources.getString(R.string.reminder_hour) + tmpVO.leftMinute
					                + resources.getString(R.string.reminder_minute), Toast.LENGTH_SHORT).show();
				}
				ReminderUtils.setReminderEnable(idList.get(position), ((CheckedTextView) view).isChecked() == false);
			}
		});
		// select item which is enabled.
		for (int i = 0; i < idList.size(); i++)
		{
			listView.setItemChecked(i, ReminderUtils.checkReminderEnable(idList.get(i)));
		}
		// add button
		Button addBtn = (Button) findViewById(R.id.addBtn);
		addBtn.setOnClickListener(new Button.OnClickListener()
		{
			@Override
			public void onClick(View v)
			{
				if (remindVO == null)
				{
					remindVO = new RemindVO();
				}
				edit = false;
				showAlertDialog();
			}
		});
		// sound file path
		ListView soundPosView = (ListView) findViewById(R.id.soundPosView);
		final List<String> setList = new ArrayList<String>();
		String posStr = ResUtils.getStringRes(ResKey.REMINDER_SOUND_POS);
		if (Constants.EMPTY.equals(posStr))
		{
			posStr = resources.getString(R.string.reminder_sound_pos_none);
		}
		setList.add(resources.getString(R.string.reminder_sound_pos) + Constants.COLON + Constants.BLANK + posStr);
		final ArrayAdapter<String> setArr = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, setList);
		soundPosView.setAdapter(setArr);
		soundPosView.setOnItemClickListener(new AdapterView.OnItemClickListener()
		{
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id)
			{
				if (soundPosSettingDialog == null)
				{
					LayoutInflater factory = LayoutInflater.from(Reminder.this);
					final View textEntryView = factory.inflate(R.layout.reminder_sound_pos, null);
					final EditText setText = (EditText) textEntryView.findViewById(R.id.soundPosText);
					setText.setText(ResUtils.getStringRes(ResKey.REMINDER_SOUND_POS));
					soundPosSettingDialog = new AlertDialog.Builder(Reminder.this)
					        .setIcon(R.drawable.ic_popup_reminder).setTitle(R.string.reminder_sound_pos).setView(
					                textEntryView).setPositiveButton(R.string.confirm_ok,
					                new DialogInterface.OnClickListener()
					                {
						                @Override
						                public void onClick(DialogInterface dialog, int whichButton)
						                {
							                // on path set...
							                String path = setText.getText().toString();
							                File file = new File(path);
							                if (file.exists() && file.isDirectory())
							                {
								                ResUtils.setRes(ResKey.REMINDER_SOUND_POS, path);
								                setList.add(resources.getString(R.string.reminder_sound_pos)
								                        + Constants.COLON + Constants.BLANK + path);
								                setArr.notifyDataSetChanged();
							                } else
							                {
								                setText.setText(ResUtils.getStringRes(ResKey.REMINDER_SOUND_POS));
								                showAlertBuilder(R.string.reminder_sound_pos_unknown, null);
							                }
						                }
					                }).setNegativeButton(R.string.confirm_cancel, new DialogInterface.OnClickListener()
					        {
						        @Override
						        public void onClick(DialogInterface dialog, int whichButton)
						        {
							        remindVO = null;
						        }
					        }).show();
				}
				soundPosSettingDialog.show();
			}
		});
	}

	private void showAlertBuilder(int resId, final AlertDialog callback)
	{
		if (alertBuilder == null)
		{
		    alertBuilder = new AlertDialog.Builder(Reminder.this).setIcon(
		            R.drawable.star).setTitle(R.string.alert)
		            .setPositiveButton(R.string.close, null);
		}
		alertBuilder.setMessage(resId);
		alertBuilder.setPositiveButton(R.string.close, new DialogInterface.OnClickListener(){
			@Override
			public void onClick(DialogInterface dialog, int which)
			{
				if (callback != null)
					callback.show();
			}
		});
        alertBuilder.show();
	}

	private Builder weekBuilder = null;
	private Builder soundBuilder = null;
	private Builder alertBuilder = null;
	private Builder menuBuilder = null;
	private Builder delConfirmBuilder = null;
	private ListView detailListView = null;
	private List<String> detailList = new ArrayList<String>();
	private AlertDialog detailDialog = null;
	private AlertDialog soundPosSettingDialog = null;
	private TimePickerDialog timePickerDialog;
	private boolean[] tmpRepeatDay = new boolean[7];
	private StringBuilder buff = new StringBuilder();
	private String[] dayStrArr = null;
	private List<String> soundStrList = new ArrayList<String>();
	private DialogInterface.OnMultiChoiceClickListener daySelectedListener = null;
	private DialogInterface.OnClickListener soundSelectedListener = null;
	private MediaPlayer mediaPlayer;
	private int soundIndex = 0;
	private String editIndex;
	private boolean edit = false;

	private void showAlertDialog()
	{
		final Resources resources = getResources();
		if (detailListView == null)
		{
			LayoutInflater factory = LayoutInflater.from(this);
			final View detailDialogView = factory.inflate(R.layout.reminder_detail, null);
			detailListView = (ListView) detailDialogView.findViewById(R.id.detailListView);
			detailList.add(ReminderUtils.getTimeItem(buff, resources, remindVO));
			dayStrArr = resources.getStringArray(R.array.select_week_n);
			detailList.add(ReminderUtils.getRepeatDayItem(buff, resources, remindVO, tmpRepeatDay, dayStrArr, edit));
			detailList.add(ReminderUtils.getSoundItem(buff, resources, remindVO));
			detailList.add(ReminderUtils.getBsWeekEnableItem(buff, resources, remindVO));
			detailList.add(ReminderUtils.getVibrateEnableItem(buff, resources, remindVO));
			final ArrayAdapter<String> settingAdapter = new ArrayAdapter<String>(this,
			        android.R.layout.simple_list_item_1, detailList);
			detailListView.setAdapter(settingAdapter);
			detailListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
			{
				@Override
				public void onItemClick(AdapterView<?> parent, View view, int position, long id)
				{
					switch (position)
					{
					case 0:
						if (timePickerDialog == null)
						{
							timePickerDialog = new TimePickerDialog(detailDialogView.getContext(),
							        new TimePickerDialog.OnTimeSetListener()
							        {
								        @Override
								        public void onTimeSet(TimePicker view, int hourOfDay, int minute)
								        {
								        	boolean exist = false;
								        	if (edit)
								        	{
								        		// TODO
								        		exist = ReminderUtils.checkReminderExist(editIndex, hourOfDay, minute);
								        	} else
								        	{
								        		exist = ReminderUtils.checkReminderExist("-1", hourOfDay, minute);
								        	}
								        	if (exist)
								        	{
								        		showAlertBuilder(R.string.reminder_time_exist, timePickerDialog);
								        		return;
								        	}
									        remindVO.hour = hourOfDay;
									        remindVO.minute = minute;
									        detailList.remove(0);
									        detailList.add(0, ReminderUtils.getTimeItem(buff, resources, remindVO));
									        settingAdapter.notifyDataSetChanged();
								        }
							        }, remindVO.hour, remindVO.minute, true);
						}
						timePickerDialog.show();
						break;
					case 1:
						if (weekBuilder == null)
						{
							weekBuilder = new AlertDialog.Builder(Reminder.this).setIcon(R.drawable.ic_popup_reminder)
							        .setTitle(R.string.reminder_add).setPositiveButton(R.string.confirm_set,
							                new DialogInterface.OnClickListener()
							                {
								                @Override
								                public void onClick(DialogInterface dialog, int whichButton)
								                {
									                detailList.remove(1);
									                detailList.add(1, ReminderUtils.getRepeatDayItem(buff, resources,
									                        remindVO, tmpRepeatDay, dayStrArr, false));
									                settingAdapter.notifyDataSetChanged();
								                }
							                }).setNegativeButton(R.string.confirm_cancel, null);
						}
						if (daySelectedListener == null)
						{
							daySelectedListener = new DialogInterface.OnMultiChoiceClickListener()
							{
								@Override
								public void onClick(DialogInterface dialog, int which, boolean isChecked)
								{
									tmpRepeatDay[which] = isChecked;
								}
							};
						}
						weekBuilder.setMultiChoiceItems(R.array.select_week, tmpRepeatDay, daySelectedListener);
						weekBuilder.show();
						break;
					case 2:
						if (soundBuilder == null)
						{
							soundBuilder = new AlertDialog.Builder(Reminder.this).setIcon(R.drawable.ic_popup_reminder)
							        .setTitle(R.string.reminder_add).setPositiveButton(R.string.confirm_set,
							                new DialogInterface.OnClickListener()
							                {
								                @Override
								                public void onClick(DialogInterface dialog, int whichButton)
								                {
									                String s = null;
									                if (soundIndex > 1)
									                {
										                // /
									                } else
									                {
										                s += soundIndex;
									                }
									                remindVO.sound = s;
									                detailList.remove(2);
									                buff.setLength(0);
									                buff.append(resources.getString(R.string.reminder_sound));
									                buff.append("  ");
									                if (soundIndex < 2)
									                {
										                buff
										                        .append(resources.getStringArray(R.array.default_sound)[soundIndex]);
									                }
									                detailList.add(2, buff.toString());
									                settingAdapter.notifyDataSetChanged();
									                if (mediaPlayer != null && mediaPlayer.isPlaying())
									                {
										                mediaPlayer.stop();
										                mediaPlayer.reset();
									                }
								                }
							                }).setNegativeButton(R.string.confirm_cancel,
							                new DialogInterface.OnClickListener()
							                {
								                @Override
								                public void onClick(DialogInterface dialog, int which)
								                {
									                if (mediaPlayer != null && mediaPlayer.isPlaying())
									                {
										                mediaPlayer.stop();
										                mediaPlayer.reset();
									                }
								                }
							                });
							soundSelectedListener = new DialogInterface.OnClickListener()
							{
								@Override
								public void onClick(DialogInterface dialog, int which)
								{
									soundIndex = which;
									if (mediaPlayer == null)
									{
										mediaPlayer = new MediaPlayer();
									}
									AssetFileDescriptor afd = null;
									switch (which)
									{
									case 0:
										afd = resources.openRawResourceFd(R.raw.s_dida);
										break;
									case 1:
										afd = resources.openRawResourceFd(R.raw.s_dream);
										break;
									}
									try
									{
										if (mediaPlayer.isPlaying())
										{
											mediaPlayer.stop();
											mediaPlayer.reset();
										}
										if (afd == null)
										{
											mediaPlayer.setDataSource(Reminder.this, Uri.fromFile(new File(ResUtils
											        .getStringRes(ResKey.REMINDER_SOUND_POS)
											        + soundStrList.get(which))));
										} else
										{
											mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
											        afd.getLength());
											afd.close();
										}
										mediaPlayer.prepare();
										mediaPlayer.start();
									} catch (Exception e)
									{
										Log.e(" play sound ", " error !!!!!!!!!!!!!!!!!!" + e.toString());
									}
								}
							};
						}
						soundStrList.clear();
						for (String s : resources.getStringArray(R.array.default_sound))
						{
							soundStrList.add(s);
						}
						File[] files = new File(ResUtils.getStringRes(ResKey.REMINDER_SOUND_POS)).listFiles();
						if (files != null)
						{
							for (File file : files)
							{
								soundStrList.add(file.getName());
							}
						}
						soundBuilder.setSingleChoiceItems(R.array.default_sound, 0, soundSelectedListener);
						soundBuilder.show();
						break;
					case 3:
						detailList.remove(3);
						remindVO.enableBsWeek = remindVO.enableBsWeek == false;
						detailList.add(3, ReminderUtils.getBsWeekEnableItem(buff, resources, remindVO));
						settingAdapter.notifyDataSetChanged();
						break;
					case 4:
						detailList.remove(4);
						remindVO.enableVibrate = remindVO.enableVibrate == false;
						detailList.add(ReminderUtils.getVibrateEnableItem(buff, resources, remindVO));
						settingAdapter.notifyDataSetChanged();
						break;
					}
				}
			});
			detailDialog = new AlertDialog.Builder(this).setIcon(R.drawable.ic_popup_reminder).setTitle(
			        R.string.reminder_add).setView(detailDialogView).setPositiveButton(R.string.confirm_ok,
			        new DialogInterface.OnClickListener()
			        {
				        @Override
				        public void onClick(DialogInterface dialog, int whichButton)
				        {
					        if (edit)
					        {
						        ReminderUtils.updateNewRemindVO(remindVO, editIndex);
						        // TODO:reset alarm
						        Integer i = Integer.valueOf(editIndex);
						        reminderAdapter.remove(reminderAdapter.getItem(i));
						        reminderAdapter.add(ReminderUtils.buildRemindStr(buff, resources, remindVO));
						        idList.remove(i);
						        idList.add(editIndex);
					        } else
					        {
						        int index = ReminderUtils.saveNewRemindVO(remindVO);
						        reminderAdapter.add(ReminderUtils.buildRemindStr(buff, resources, remindVO));
						        idList.add(String.valueOf(index));
						        Constants.ALERT_SENDER_MAP.put(String.valueOf(index), PendingIntent.getBroadcast(Reminder.this,
						                index, alertIntent, index));
					        }
					        remindVO = null;
				        }
			        }).setNegativeButton(R.string.confirm_cancel, new DialogInterface.OnClickListener()
			{
				@Override
				public void onClick(DialogInterface dialog, int whichButton)
				{
					remindVO = null;
				}
			}).show();
		} else
		{
			detailList.clear();
			detailList.add(ReminderUtils.getTimeItem(buff, resources, remindVO));
			detailList.add(ReminderUtils.getRepeatDayItem(buff, resources, remindVO, tmpRepeatDay, dayStrArr, true));
			detailList.add(ReminderUtils.getSoundItem(buff, resources, remindVO));
			detailList.add(ReminderUtils.getBsWeekEnableItem(buff, resources, remindVO));
			detailList.add(ReminderUtils.getVibrateEnableItem(buff, resources, remindVO));
			((BaseAdapter) detailListView.getAdapter()).notifyDataSetChanged();
			detailDialog.show();
		}
	}
}
